<template>
  <el-card shadow="hover" style="width: 350px">
    <template #header>
      <div class="option-header">
        <div class="option-header-content"><span>单鲨期权</span></div>
        <div v-if="props.calcSuccess=='true'" class="option-header-content"><span style="color: #22bb98 ">计算成功</span>
        </div>
        <!--        <div v-if="props.calcSuccess=='false'" class="option-header-content"><span style="color: #e53c3c">计算失败</span></div>-->
        <div v-if="props.calcSuccess=='false'" class="option-header-content">
          <el-tooltip effect="light">
            <template #content>
              <div style="width: 280px;">
                <span style="color: #e53c3c;">{{ props.errorMsg }}</span>
              </div>
            </template>
            <span style="color: #e53c3c">计算失败</span>
          </el-tooltip>
        </div>
        <div>
          <el-button style="background: transparent;" :disabled="cpoyWait" v-if="props.useType=='calc'" class="delete"
                     @click="copy" title="复制">
            <el-icon>
              <copy-document/>
            </el-icon>
          </el-button>
          <el-button style="background: transparent;" class="delete" @click="cancel" title="关闭">
            <el-icon>
              <circle-close/>
            </el-icon>
          </el-button>
        </div>
      </div>
    </template>

    <el-form ref="formRef" :disabled="form.data.readOnly" :model="form.data" label-width="auto" size="small"
             :rules="rules">
      <div class="optionst01">
        <el-form-item label="观察方式">
          <el-radio-group v-model="form.data.exerciseType" size="small" :fill="getColor()">
            <el-radio label="European">欧式观察</el-radio>
            <el-radio label="American">美式观察</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="交易方向" prop="payDirection">
          <el-radio-group v-model="form.data.payDirection" size="small" :fill="getColor()">
            <el-radio-button label="1">买入</el-radio-button>
            <el-radio-button label="-1">卖出</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="标的" label-width="auto" prop="instrumentId">
          <Underlyer v-model="form.data.instrumentId" :underlyerId="form.data.instrumentId" @change="onBlurInstrumentId" :filterDate="true" ref="underlyerIdRef"/>
        </el-form-item>
        <!--合约乘数-->
        <!--      todo-->
        <!--涨跌类型-->
        <el-form-item label="涨跌类型" label-width="auto" prop="optionType">
          <el-radio-group v-model="form.data.optionType" size="small">
            <el-radio label="Call">看涨</el-radio>
            <el-radio label="Put">看跌</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="起始日" label-width="auto" prop="effectiveDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.effectiveDate" @blur="onBlurEffectiveDate" type="date" placeholder="">
          </el-date-picker>
        </el-form-item>

        <el-form-item label="期限" label-width="auto" prop="term">
          <Numberinput min="1" maxlength="4" v-model="form.data.term" append="D"/>
        </el-form-item>

        <el-form-item :label="form.data.exerciseType === 'European'?'观察日':'到期日'" label-width="auto"
                      prop="terminationDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.terminationDate" type="date" placeholder=""/>
        </el-form-item>

        <el-form-item label="到期支付偏移" label-width="auto" prop="paymentDaysOffset">
          <Numberinput v-model="form.data.paymentDaysOffset" maxlength="4" append="D"/>

        </el-form-item>

        <el-form-item label="到期支付日" label-width="auto" prop="terminationPaymentDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.terminationPaymentDate"
                          type="date"
                          placeholder=""/>
        </el-form-item>

        <el-form-item v-if="startRequired" label="观察开始日" label-width="auto"
                      prop="startDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.startDate" type="date" placeholder="">
          </el-date-picker>
        </el-form-item>
        <el-form-item v-if="endRequired" label="观察结束日" label-width="auto" prop="endDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.endDate" @blur="endDateChange" type="date" placeholder="">
          </el-date-picker>
        </el-form-item>

        <el-form-item label="名义本金" prop="notional">
          <InputAmount v-model:value="form.data.notional" maxlength="20" append="元" precision="2"></InputAmount>
        </el-form-item>

        <el-form-item label="期初价格" label-width="auto" prop="spotPrice" >
          <el-col :span="8">
            <el-checkbox name="status" false-label="0" true-label="1" maxlength="20" v-model="form.data.priceOnWait">
              待定
            </el-checkbox>
          </el-col>
          <el-col :span="16">
            <InputAmount v-model:value="form.data.spotPrice" @change="() => {proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''}" maxlength="20" :disabled="form.data.priceOnWait=='1'"
                         precision="2" append="元"/>
          </el-col>
        </el-form-item>

        <el-form-item label="交易数量" prop="optionEntitlement">
          <Numberinput v-model="form.data.optionEntitlement" precision="2" maxlength="20"
                       :disabled="form.data.priceOnWait=='1'"
                       @change="optionEntitlementChange"/>
        </el-form-item>
        <el-form-item label="参与率" prop="participationRate">
          <Numberinput v-model="form.data.participationRate" maxlength="20" precision="2" append="%"/>
        </el-form-item>
      </div>
      <!---------------------------------------------- 分割线---------------------------------------------------------->
      <div class="optionst02">

        <el-form-item label="行权价" prop='strikePercentage'>
          <el-col :span="12">
            <Numberinput v-model="form.data.strikePercentage" maxlength="18" @blur="linkPercentage(form,form.data.strikePercentage,form.data.spotPrice,'data.strike')" append="%"
                         @change="() => {proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''}"
                         :input-style="Dialog.type=='strikePercentage'?'color: red;':''"
                         precision="2"/>
          </el-col>
          <el-col :span="12">
            <InputAmount v-model:value="form.data.strike" maxlength="20" @blur="linkPrice(form,form.data.strike,form.data.spotPrice,'data.strikePercentage')"
                         @change="() => {proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''}"
                         :input-style="Dialog.type=='strikePercentage'?'color: red;':''"
                         append="元" precision="2"/>
          </el-col>

        </el-form-item>
        <el-form-item label="是否年化">
          <dictCombox v-model="form.data.moneynessOption"
                      dictType="boolType" @change="moneynessOptionChange"
                      :style="{width: '100%'}"></dictCombox>
        </el-form-item>
        <el-form-item label="敲出方向" prop='knockType'>
          <dictCombox v-model="form.data.knockType"
                      dictType="touchknockType" disabled></dictCombox>
        </el-form-item>

        <el-form-item label="观察频率" prop='scheduleType'>
          <dictCombox v-model="form.data.scheduleType"
                      dictType="scheduleType" disabled></dictCombox>
        </el-form-item>

        <el-form-item label="支付时机" prop='payStyle'>
          <dictCombox v-model="form.data.payStyle"
                      dictType="compensateDay"></dictCombox>
        </el-form-item>
        <el-form-item label="障碍价比例" prop='triggerRate'>
          <Numberinput v-model="form.data.triggerRate" maxlength="20" @blur="linkPercentage(form,form.data.triggerRate,form.data.spotPrice,'data.triggerPrice')" precision="2"
                       :input-style="Dialog.type=='triggerRate'?'color: red;':''" append="%"/>
        </el-form-item>
        <el-form-item label="障碍价"  prop='triggerPrice'>
          <Numberinput v-model="form.data.triggerPrice" @blur="linkPrice(form,form.data.triggerPrice,form.data.spotPrice,'data.triggerRate')" maxlength="20" precision="2"
                         :input-style="Dialog.type=='triggerRate'?'color: red;':''"/>
        </el-form-item>
        <el-form-item label="敲出补偿比例" prop='rebateRate'>
          <el-col :span="8">
            <el-checkbox v-model="form.data.midMoneynessOption" false-label="0" true-label="1">年化</el-checkbox>
          </el-col>
          <el-col :span="16">
            <Numberinput v-model="form.data.rebateRate" maxlength="20" @blur="onRebateRateChange" precision="2"
                         :input-style="Dialog.type=='rebateRate'?'color: red;':''" append="%"/>
          </el-col>
        </el-form-item>
        <el-form-item label="敲出补偿金额"  prop='rebatePrice'>
          <Numberinput v-model="form.data.rebatePrice" @blur="onRebatePriceChange" precision="2"
                       :input-style="Dialog.type=='rebateRate'?'color: red;':''"/>
        </el-form-item>
        <el-form-item label="最低收益率" prop='minYieldRate'>
          <el-col :span="8">
            <el-checkbox v-model="form.data.lowMoneynessOption" false-label="0" true-label="1">年化</el-checkbox>
          </el-col>
          <el-col :span="16">
            <Numberinput v-model="form.data.minYieldRate" maxlength="20" @input="onMinYieldRateChange" precision="2"
                         :input-style="Dialog.type=='minYieldRate'?'color: red;':''" append="%"/>
          </el-col>
        </el-form-item>
        <el-form-item label="最低收益"  prop='minYieldPrice'>
          <Numberinput v-model="form.data.minYieldPrice" precision="2" maxlength="20" @blur="onMinYieldPriceChange"
                       :input-style="Dialog.type=='minYieldRate'?'color: red;':''"/>
        </el-form-item>

        <el-form-item label="计息天数" v-if="false"
                      v-show="moneyOptionFlag ||form.data.midMoneynessOption=='1'||form.data.lowMoneynessOption=='1'"
                      prop="daycounterTerm">
          <Numberinput v-model="form.data.term" append="D"/>
        </el-form-item>

        <el-form-item label="计息基准"
                      v-show="moneyOptionFlag||form.data.midMoneynessOption=='1'||form.data.lowMoneynessOption=='1'"
                      prop="daycounter">
          <dictCombox v-model="form.data.daycounter" prop='disDayCount'
                      dictType="dayCounter"
                      :style="{width: '100%'}"></dictCombox>
        </el-form-item>

        <el-form-item class="operation">

          <el-button type="primary" @click="calc" v-show="props.useType=='calc'||props.useType=='scene'"
                     :disabled="form.data.priceOnWait=='1'">计算
          </el-button>
          <el-button type="primary" @click="calcInvert" v-show="props.useType=='calc'||props.useType=='scene'"
                     :disabled="form.data.priceOnWait=='1'">反算
          </el-button>
          <el-button @click="save2CalcLog" v-show="props.useType=='calc'" :disabled="form.data.priceOnWait=='1'">存为草稿
          </el-button>

        </el-form-item>
      </div>
    </el-form>
    <div class="optionst03">
      <PricingParam ref="PricingParamRef" :formData="form.data"  :valueDate="props.valueDate"  size="small" label-width="auto" :productType="productType"
                    :disabled="form.data.readOnly" :index="props.index"
                    :calcPricingParam="props.calcPricingParam"></PricingParam>
    </div>
    <!--  todo 情景因子  -->
    <!--  todo 结果  -->
    <div v-show="props.useType!='scene'">
      <!--      <singleResult ref="resultCompRef" :result="form.result" :index="props.index"
                          :calcMarketNpv="props.useType=='calc'"></singleResult>-->
      <singleResult ref="resultCompRef" :result="form.result" :index="props.index" :form="form"
                    :calcInvert="props.useType=='calc'"></singleResult>
    </div>
    <div v-if="props.useType!='scene'&&showVolRatesResult">
      <volRatesResult :calcMarketNpvResult="props.calcMarketNpvResult"/>
    </div>
  </el-card>
  <el-dialog
      custom-class="calcInvert"
      v-model="calcInvertVisible"
      title="反算结果"
      width="20%"
      destroy-on-close
      center
      :modal-append-to-body="false" draggable
      :close-on-click-modal="false" :modal='false' :lock-scroll="false" :append-to-body="false"
      :close-on-press-escape="false"
  >
    <el-table
        :data="Dialog.data"
        height="450"
        :show-header="false"
        stripe
        @row-dblclick="dbClickForInvert"
        :cell-style="{ padding:'9px',margin:'9px',cellspacing:'9px' }"
        style="width: 100%">
      <el-table-column type="index" width="50"/>
      <el-table-column
          prop="date"
          width="auto">
        <template #default="scope">
          <el-form ref="DialogForm" disabled label-width="auto" size="small">
            <el-form-item v-if="Dialog.showMoneynessOption" :label="scope.row.labelPercentage">
              <el-col :span="8">
                <el-checkbox v-model="Dialog.moneynessOption" name="status" false-label="0" true-label="1">年化
                </el-checkbox>
              </el-col>
              <el-col :span="16">
                <Numberinput v-model="scope.row.valuePercentage" maxlength="18" precision="2" append="%"/>
              </el-col>
            </el-form-item>
            <el-form-item v-if="!Dialog.showMoneynessOption" :label="scope.row.labelPercentage">
              <Numberinput v-model="scope.row.valuePercentage" maxlength="18" precision="2" append="%"/>
            </el-form-item>
            <el-form-item :label="scope.row.labelAmount">
              <Numberinput v-model="scope.row.valueAmount" maxlength="18" precision="2" append="元"/>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>

<script setup>
import {linkPercentage,linkPrice}  from '@/views/calc/otcOtion/instrument/common/formula'
import {getCurrentInstance, onMounted, onUpdated, provide, reactive, ref, toRaw, toRefs, watch, watchEffect} from 'vue'
import Underlyer from '../../../../xquant/base/underlyer'
import Numberinput from '../../../../xquant/base/number'
import InputAmount from '../../../../xquant/base/InputAmount'
import volRatesResult from '@/views/calc/otcOtion/result/volRatesResult'
import dictCombox from '@/xquant/base/dictCombox'
import PricingParam from '@/views/calc/otcOtion/pricingparam/index'
import singleResult from '@/views/calc/otcOtion/result/single'
import {getTradeDay} from '@/utils/calc'
import {getTerminationPaymentDate, getOffset, calcContractParamProxy} from '@/api/calc/otcOption/calc'
import {formartFormP4, formartTableP2, unFormartNumber, formartFormP2, numberPrecision} from '@/utils/numberUtil'
import * as Util from '../../../../utils/util'
import {debounce} from 'lodash'
import {setCommonSpotPrice} from '@/views/calc/otcOtion/instrument/common/common'
import {isNotVoid,calcAnnualizedByTerminationPaymentDate, isVoid} from "../../../../utils/util";
import {computeType} from "./common/data";
import { nextTick } from 'vue'
import {validateDates} from "./common/validate";
const cpoyWait = ref(false)
const getColor = () => {
  return form.data.payDirection == '1' ? '#E53C3C' : '#22BB98'
}
const {proxy} = getCurrentInstance()
const productType = 'SingleSharkFin'
const showVolRatesResult = ref(false)
const startRequired = ref(false)
const endRequired = ref(false)
const labelWidth = ref('111px')
const moneyOptionFlag = ref(true)
const form = reactive({
  data: {
    productType: 'SingleSharkFin',
    payDirection: '1',
    instrumentId: null,
    optionType: 'Call',
    effectiveDate: proxy.$moment(new Date()).format('YYYY-MM-DD'),
    terminationDate: '',
    terminationPaymentDate: '',
    term: '30',
    paymentDaysOffset: '0',
    priceOnWait: '0',
    spotPrice: '',
    strikePercentage: '100',
    triggerRate: '',
    triggerPrice: '',
    rebateRate: '',
    rebatePrice: '',
    minYieldRate: '',
    minYieldPrice: '',
    strike: 0,
    notional: '',
    scheduleType: '',
    knockType: '',
    optionEntitlement: '',
    moneynessOption: '1',
    midMoneynessOption: '1',
    lowMoneynessOption: '1',
    daycounter: 'Actual/365',
    participationRate: 100,
    calendar: 'CHINA_EX',
    daycounterTerm: '365',
    exerciseType: 'European',
    isIncludeEndDate: '',
    endDate: '',
    isIncludeStartDate: '',
    startDate: '',
    payStyle: 'Deferred',
  },
  result: {},
  initFlag: ''
})
const calcInvertVisible = ref(false)
const Dialog = reactive({
  showMoneynessOption: true,
  moneynessOption:false,
  type: '',
  data: [{
    valueAmount: '',
    labelAmount: '',
    valuePercentage: '',
    labelPercentage: '',
    moneynessOption: ''
  }]
})
const rules = {
  payDirection: [{required: true, message: '请选择交易方向', trigger: 'change'}],
  instrumentId: [{required: true, message: ' ', trigger: 'change'}],
  optionType: [{required: true, message: '请选择涨跌类型', trigger: 'change'}],
  effectiveDate: [{required: true, message: ' ', trigger: 'change'}],
  terminationDate: [{required: true, message: ' ', trigger: 'change'}],
  term: [{required: true, message: ' ', trigger: 'change'}],
  paymentDaysOffset: [{required: true, message: ' ', trigger: 'change'}],
  notional: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  daycounter: [{required: true, message: ' ', trigger: 'change'}],
  daycounterTerm: [{required: true, message: ' ', trigger: 'change'}],
  spotPrice: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1') {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  optionEntitlement: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1') {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  strike: [{required: true, message: ' ', trigger: 'blur'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1'&&Number(form.data.strikePercentage)>0) {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  strikePercentage: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1'&&Number(form.data.strike)>0) {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  triggerRate: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1'&&Number(form.data.triggerPrice)>0) {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  triggerPrice: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1'&&Number(form.data.triggerRate)>0) {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  rebateRate: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  rebatePrice: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  participationRate: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  paymentAmountPecentage: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  paymentAmount: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  minYieldRate: [{required: false, message: ' ', trigger: 'change'}],
  minYieldPrice: [{required: false, message: ' ', trigger: 'change'}],
  startDate: [{required: startRequired, message: ' ', trigger: 'change'}],
  endDate: [{required: endRequired, message: ' ', trigger: 'change'}]

}

watch(() => props.result, (nv, ov) => {
  let other = {
    'type': '单鲨',
    '标的': computed(() => {
      if (proxy.$refs.underlyerIdRef && proxy.$refs.underlyerIdRef.underlyerIdsList[0]) {
        return (proxy.$refs.underlyerIdRef.underlyerIdsList[0].productName + '').trim().split(' ').join(',')
      }
    }),
    '交易日期': props.valueDate,
    '观察方式': form.data.exerciseType == 'European' ? '欧式观察' : '美式观察',
    '合约类型': form.data.optionType == 'Call' ? 'C' : 'P',
    '合约交易方向': form.data.payDirection == '1' ? '客户卖价' : '客户买价',
    '到期日': form.data.terminationDate,
    '执行价': formartFormP2(form.data.strike),
    '敲出方向': form.data.knockType == 'up' ? '向上' : '向下',
    '观察频率': form.data.scheduleType == 0 ? '连续观察' : (form.data.scheduleType == 1 ? '按日观察' : (form.data.scheduleType == 2 ? '到期' : '其他')),
    '障碍价比例': formartFormP2(form.data.triggerRate),
    '敲出补偿比例': formartFormP2(form.data.rebateRate),
    '最低收益率': formartFormP2(form.data.minYieldRate),
    '数量': formartFormP2(form.data.optionEntitlement),
    '名义金额': formartFormP2(form.data.notional),
    '开仓标的价': formartFormP2(form.data.spotPrice),
    '期权单价': computed(() => {
      if (nv) {
        return formartFormP2(nv.npv / form.data.optionEntitlement)
      }
    }),
    '百分比估值': computed(() => {
      if (nv) {
        return formartFormP2(100 * nv.npv / form.data.notional)
      }
    }),
  }
  form.result = Object.assign(other, nv)
}, {immediate: true})
watch(() => form.data.priceOnWait, (nv, ov) => {
  if (nv == '1') {
    form.data.spotPrice = 0
  } else {
    setSpotPrice()
  }
})
watch(() => form.data.optionType, (nv, ov) => {
  if (nv == 'Call') {
    form.data.knockType = 'up'
  } else {
    form.data.knockType = 'down'
  }
}, {
  immediate: true
})


/*
* 修改状态  false:当前没有操作  true:当前在被其他方法操作
* */
const lock = reactive({
  paymentDaysOffset: false,
  terminationPaymentDate: false,
})

watch(() => form.data.paymentDaysOffset, (nv, ov) => {
  if (nv === '') return
  if (lock.terminationPaymentDate) return
  lock.terminationPaymentDate = true
  onpaymentDaysOffsetChange()
})
const onpaymentDaysOffsetChange = debounce(function () {
  getTerminationPaymentDate({
    'calDay': form.data.terminationDate,
    'offset': form.data.paymentDaysOffset
  }).then(response => {
    lock.terminationPaymentDate = false
    if (response.errorCode != 0) {
    } else {
      if (response.result) {
        form.data.terminationPaymentDate = response.result.CAL_DAY
      }
    }
  })
}, 1000)
watch(() => [form.data.terminationDate], ([nv], [ov]) => {
  if (nv == ov || nv === '') return
  onterminationPaymentDate()
})
const onterminationPaymentDate = debounce(function (nv, ov) {
  getOffset({
    'day': form.data.terminationPaymentDate,
    'calDay': form.data.terminationDate
  }).then(response => {
    if (response.errorCode != 0) {

    } else {
      if (response.result == null) {
        onpaymentDaysOffsetChange()
        return
      }
      form.data.paymentDaysOffset = response.result.i
      lock.paymentDaysOffset = false
    }
  })
}, 1000)

onUnmounted(() => {
  // 移除组件时，取消定时器
  onpaymentDaysOffsetChange.cancel()
  onterminationPaymentDate.cancel()
})
watch(() => [form.data.terminationPaymentDate], ([nv], [ov]) => {
  if (nv == ov || nv === '') return
  if (lock.paymentDaysOffset) return
  lock.paymentDaysOffset = true
  onterminationPaymentDate()
})
const onBlurTerminationDate = (nv, ov) => {
  let a = proxy.$moment(form.data.terminationDate)
  let b = proxy.$moment(form.data.terminationPaymentDate)
  form.data.paymentDaysOffset = b.diff(a, 'days')
}
watch(() => [form.data.effectiveDate, form.data.terminationDate], ([nv, n2v], [ov, o2v]) => {
  if (!proxy.lsh.isEmpty(nv) && !proxy.lsh.isEmpty(n2v)) {
    let a = proxy.$moment(n2v)
    let b = proxy.$moment(nv)
    form.data.term = Number(a.diff(b, 'days'))
   proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }
})
watch(() => [form.data.term], ([newValue], [oldValue]) => {
  if (Util.isNotVoid(String(form.data.effectiveDate)) && Util.isNotVoid(String(newValue))) {
    let a = proxy.$moment(form.data.effectiveDate)
    form.data.terminationDate = a.add(newValue, 'days').format('YYYY-MM-DD')
    form.data.endDate = form.data.terminationDate
    form.data.startDate = form.data.effectiveDate
    onpaymentDaysOffsetChange()
    onMinYieldRateChange()
    onRebateRateChange()
  }
})
watch(() => [form.data.notional, form.data.spotPrice], ([nv, n2v], [ov, o2v]) => {
  if (!proxy.lsh.isEmpty(nv) && !proxy.lsh.isEmpty(n2v)) {

    form.data.optionEntitlement = String(Number(nv) / Number(n2v))
  }
})


watch(() => [form.data.notional], ([newValue], [oldValue]) => {
  if (optionEntitlementLinkValid(newValue, form.data.spotPrice, form.data.optionEntitlement)) {
    return
  }
  if (Util.isNotVoid(String(newValue))) {
    if (Util.isNotVoid(String(form.data.spotPrice))) {
      form.data.optionEntitlement = proxy.lsh.round(proxy.lsh.divide(newValue, form.data.spotPrice), 4)
      return
    }
    if (Util.isNotVoid(String(form.data.optionEntitlement))) {
      form.data.spotPrice = proxy.lsh.round(proxy.lsh.divide(newValue, form.data.optionEntitlement), 4)
      return
    }
  }
})
watch(() => [form.data.spotPrice], ([newValue], [oldValue]) => {
  if (optionEntitlementLinkValid(form.data.notional, newValue, form.data.optionEntitlement)) {
    return
  }

  if (Util.isNotVoid(String(newValue))) {
    if (Util.isNotVoid(String(form.data.notional))) {
      form.data.optionEntitlement = proxy.lsh.round(proxy.lsh.divide(form.data.notional, newValue), 4)
      return
    }
    if (Util.isNotVoid(String(form.data.optionEntitlement))) {
      form.data.notional = proxy.lsh.round(proxy.lsh.multiply(form.data.optionEntitlement, newValue), 4)
      return
    }
  }
})
const optionEntitlementChange = (newValue) => {
  if (form.data.priceOnWait == '1') return
  if (optionEntitlementLinkValid(form.data.notional, form.data.spotPrice, newValue)) {
    return
  }
  if (Util.isNotVoid(String(newValue))) {
    if (Util.isNotVoid(String(form.data.spotPrice))) {
      form.data.notional = proxy.lsh.round(proxy.lsh.multiply(newValue, form.data.spotPrice), 0)
      return
    }
    if (Util.isNotVoid(String(form.data.notional))) {
      form.data.spotPrice = proxy.lsh.round(proxy.lsh.divide(form.data.notional, newValue), 4)
      return
    }
  }
}


watch(() => [form.data.notional], ([newValue], [oldValue]) => {
  if (Util.isNotVoid(String(newValue))) {
    //敲出补偿
    if (!rebateRateLinkValid(newValue, form.data.rebateRate, form.data.rebatePrice)) {
      if (Util.isNotVoid(String(form.data.rebateRate))) {
        onRebateRateChange()
      } else if (Util.isNotVoid(String(form.data.strike))) {
        form.data.rebateRate = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(form.data.rebatePrice, newValue), 100), 4)
      }
    }
    //最低收益率
    if (!minYieldLinkValid(newValue, form.data.minYieldRate, form.data.minYieldPrice)) {
      if (Util.isNotVoid(String(form.data.minYieldRate))) {
        onMinYieldRateChange()
      } else if (Util.isNotVoid(String(form.data.strike))) {
        form.data.minYieldRate = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(form.data.minYieldPrice, newValue), 100), 4)
      }
    }
  }
})


watch(() => [form.data.spotPrice], ([newValue], [oldValue]) => {
  linkPrice(form,form.data.strike,form.data.spotPrice,'data.strikePercentage')
})

const onStrikeChange = () => {
  let newValue = form.data.strike
  if (Util.isNotVoid(String(form.data.spotPrice))) {
    form.data.strikePercentage = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(newValue, form.data.spotPrice), 100), 4)
    proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }
}

const moneynessOptionChange = () => {
  if (form.data.moneynessOption == '1') {
    moneyOptionFlag.value = true
  } else {
    moneyOptionFlag.value = false
  }
}

watch(() => [form.data.midMoneynessOption], ([newValue], [oldValue]) => {
  onRebateRateChange()
})
watch(() => [form.data.lowMoneynessOption], ([newValue], [oldValue]) => {
  onMinYieldRateChange()
})


const onRebatePriceChange = () => {
  let a = form.data.rebatePrice
  if (Util.isNotVoid(String(form.data.spotPrice))) {
    if (form.data.midMoneynessOption == '1'){
      let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
      form.data.rebateRate = proxy.lsh.round(
          proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.divide(a,form.data.notional),annualized),100),2
      )
    }else {
      form.data.rebateRate = proxy.lsh.round(
          proxy.lsh.multiply(proxy.lsh.divide(a,form.data.notional),100),2
      )
    }
    return
  }
}

const onRebateRateChange = () => {
  let a = form.data.rebateRate
  if (Util.isNotVoid(String(form.data.notional))) {
    if (form.data.midMoneynessOption == '1'){
      let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
      form.data.rebatePrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.multiply(a,annualized), 100), form.data.notional), 4)

    }else {
      form.data.rebatePrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(a, 100), form.data.notional), 4)
    }
    return
  }
}

const onMinYieldPriceChange = () => {
  let a = form.data.minYieldPrice
  if (Util.isNotVoid(String(form.data.notional))) {
    if (form.data.lowMoneynessOption == '1') {
      let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
      form.data.minYieldRate = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.divide(a,annualized), form.data.notional), 100), 2)
    }else {
      form.data.minYieldRate = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(a, form.data.notional), 100), 2)
    }
    return
  }
}

const onMinYieldRateChange = ()=> {
  let a = form.data.minYieldRate
  if (Util.isNotVoid(String(form.data.notional))) {
    if (form.data.lowMoneynessOption == '1') {
      let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
      form.data.minYieldPrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.multiply(a,annualized), 100), form.data.notional), 4)
    }else {
      form.data.minYieldPrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(a, 100), form.data.notional), 4)
    }

    return
  }
}
function strikeLinkValid(spotPrice, strikePercentage, strike) {
  if (Util.isNotVoid(String(spotPrice)) && Util.isNotVoid(String(strikePercentage)) && Util.isNotVoid(String(strike))) {
    if (proxy.lsh.isEqual(strike, proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(strikePercentage, 100), spotPrice), 4))) {
      return true
    } else {
      return false
    }
  }
}



//敲出补偿
function rebateRateLinkValid(notional, rebateRate, rebatePrice) {
  if (Util.isNotVoid(String(notional)) && Util.isNotVoid(String(rebateRate)) && Util.isNotVoid(String(rebatePrice))) {
    let currentRebatePrice;
    if (form.data.midMoneynessOption == '1'){
      let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
      currentRebatePrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.multiply(form.data.rebateRate,annualized), 100), form.data.notional), 4)

    }else {
      currentRebatePrice = proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(form.data.rebateRate, 100), form.data.notional), 4)
    }
    if (proxy.lsh.isEqual(rebatePrice, currentRebatePrice)) {
      return true
    } else {
      return false
    }
  }
}

//最低收益率
function minYieldLinkValid(notional, minYieldRate, minYieldPrice) {
  if (Util.isNotVoid(String(notional)) && Util.isNotVoid(String(minYieldRate)) && Util.isNotVoid(String(minYieldPrice))) {
    if (proxy.lsh.isEqual(minYieldPrice, proxy.lsh.round(proxy.lsh.multiply(proxy.lsh.divide(minYieldRate, 100), notional), 4))) {
      return true
    } else {
      return false
    }
  }
}

function optionEntitlementLinkValid(notional, spotPrice, optionEntitlement) {
  if (Util.isNotVoid(String(notional)) && Util.isNotVoid((String(spotPrice))) && Util.isNotVoid(String(optionEntitlement))) {
    if (proxy.lsh.isEqual(optionEntitlement, proxy.lsh.round(proxy.lsh.divide(notional, spotPrice), 4))) {
      return true
    } else {
      return false
    }
  }
}

watch(() => [props.cfgId,form.data.instrumentId], ([newId, oldId]) => {
  getPricingCfg()
  setTimeout(() => {
    proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }, 1000);
})

const onBlurInstrumentId = (v) => {
  if(isNotVoid(form.data.instrumentId)){
    setSpotPrice()
    getPricingCfg()
    setTimeout(() => {
      proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
    }, 1000);
  }
}
watch(() => props.valueDate, (newValue, oldValue) => {
  if (newValue != oldValue) {
    setSpotPrice()
    //触发修改定价参数的价格
    proxy.$refs.PricingParamRef.setSpotPrice({
      valueDate: props.valueDate,
      instrumentId: form.data.instrumentId
    })
   proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }
})
const onBlurEffectiveDate = () => {
  form.initFlag = false
  setSpotPrice()
}

watch(() => form.data.exerciseType, (nv, ov) => {
  if (form.data.exerciseType == 'American') {
    startRequired.value = true
    endRequired.value = true
    if (form.data.startDate == null || form.data.startDate == "") {
      form.data.startDate = form.data.effectiveDate
    }
    if (form.data.endDate == null || form.data.endDate == "") {
      form.data.endDate = form.data.terminationDate
    }
    form.data.scheduleType = '1'
  } else {
    startRequired.value = false
    endRequired.value = false
    form.data.scheduleType = '2'
  }
}, {
  immediate: true
})

const props = defineProps({
  /*是否为重放*/
  isReCalc: {
    type: Boolean,
    default: false
  },
  calcSuccess: {
    type: String,
    default: ''
  },
  errorMsg: {
    type: String,
    default: ''
  },
  calcMarketNpvResult: {
    type: Object,
    default: {}
  },
  useType: {
    type: String,
    default: 'calc'
  },
  index: {
    type: String,
    default: ''
  },
  del: {
    type: Function,
    default: null
  },
  copy: {
    type: Function,
    default: null
  },
  calc: {
    type: Function,
    default: null
  },
  marketNPV: {
    type: Function,
    default: null
  },
  save2Trade: {type: Function, default: null},
  save2CalcLog: {type: Function, default: null},
  getDefaultCfg: {
    type: Function,
    default: null
  },
  calcPricingParam: {
    type: Object,
    default: {}
  },
  result: {
    type: Object,
    default: {}
  },
  setformData: {
    type: Function,
    default: null
  },
  formData: {
    type: Object,
    default: null
  },
  cfgId: {type: String, default: ''},
  valueDate: {type: String, default: ''}
})
/**
 * 获取计算结果
 * */
const getResult = () => {
  var data = []
  for (var item in props.result) {
    if (['npv', 'delta', 'gamma', 'vega', 'theta', 'rho', 'spotPrice', 'dscRate'].includes(item)) {
      data.push({
        key: item,
        val: proxy.lsh.ceil(props.result[item], 4)
      })
    }
  }
  return data
}
/**
 * 获取定价参数
 * */
const getPricingCfg = async () => {
  let query = {
    'calcPricingParam': {
      'cfgId': props.cfgId
    },
    'instrument': {
      'productType': 'SingleSharkFin',
      'termsheet': {
        'underlyerIds': [form.data.instrumentId],
        'customLegs': [{
          'legId': 'leg01',
          'productType': 'SingleSharkFin'
        }
        ],
        'legs': [{
          'legId': 'leg01',
          'payDirection': '1'
        }
        ]
      }
    }
  }
  //设置定价参数中的定盘价
  proxy.$refs.PricingParamRef.setSpotPrice({
    valueDate:props.valueDate,
    instrumentId:form.data.instrumentId
  })
  if (props.getDefaultCfg != null) {
    props.getDefaultCfg(query, props.index)
  }
}
/**
 * 删除
 * */
const cancel = () => {
  props.del(props.index)
}
/**
 * 复制
 * */
const copy = () => {
  props.copy(props.index)
  cpoyWait.value = true;
  setTimeout(() => {
    cpoyWait.value = false;
  }, 1000);
}
/**
 * 计算
 * */
const calc = (flag) => {
  /*flag 标识 为All时单次计算不会提示成功或失败*/
  getInstrumentJson().then((res) => {
    if (Boolean(res)) {
      let otcOption = res.otcOption
      otcOption.calcInstrumentForm = res.calcInstrumentForm
      otcOption.calcPricingForm = res.calcPricingForm
      if (otcOption != '') {
        props.calc(otcOption, props.index, flag)
      }
      showVolRatesResult.value = false
    }
  })
}

function convertJson(calcType) {

  let calcPriceParam = getCalcPriceParam(calcType)
  //界面数值不变 直接在后台传入的参数中处理敲出和保底的年化
  let tempRebateRate = form.data.rebateRate / 100
  let tempRebatePrice = form.data.rebatePrice
  if (form.data.midMoneynessOption == '1') {
    let annualized = Util.calcAnnualizedByTerminationPaymentDate(form.data)
    tempRebatePrice = form.data.notional * (tempRebateRate / 1) * annualized
    tempRebateRate = annualized * tempRebateRate
  }
  let tempMinYieldRate = form.data.minYieldRate / 100
  let tempMinYieldPrice = form.data.minYieldPrice
  if (form.data.lowMoneynessOption == '1') {
    let annualized = Util.calcAnnualizedByTerminationPaymentDate(form.data)
    tempMinYieldPrice = form.data.notional * (tempMinYieldRate / 1) * annualized
    tempMinYieldRate = annualized * tempMinYieldRate
  }
  let otcOption = {}
  otcOption = {
    instrument: {
      'productType': 'SingleSharkFin',
      'termsheet': {
        'notional': form.data.notional,
        'notionalCurrency': 'CNY',
        'settlementType': 'Cash',
        'settlementCurrency': 'CNY',
        'effectiveDate': form.data.effectiveDate,
        'effectiveDateConv': 'FOLLOWING',
        'terminationDate': form.data.terminationDate,
        'terminationDateConv': 'FOLLOWING',
        'terminationDateCalendar': form.data.calendar,
        'underlyerIds': [
          form.data.instrumentId
        ],
        'calendars': [
          form.data.calendar
        ],
        'legs': [
          {
            'legId': 'leg01',
            'payDirection': form.data.payDirection
          }
        ],
        'customLegs': [
          {
            'legId': 'leg01',
            'productType': 'SingleSharkFin',
            periodOfAccrualInterestAdjust: '0',
            'underlyers': [
              {
                'instrumentId': form.data.instrumentId,
                'quoteType': 'Close',
                'spotPrice': form.data.spotPrice,
                'fixingDate': form.data.endDate,
                'fixingDateConv': 'Preceding',
                'fixingDateCalendar': form.data.calendar
              }
            ],
            'knock': {
              'payDirection': form.data.payDirection,
              'trigger': {
                'levelPercentage': form.data.triggerRate / 100,
                'level': form.data.triggerPrice,
                'type': form.data.optionType == 'Call' ? 'EqualOrGreater' : 'EqualOrLess'
              },
              'observeDates': {
                'startDate': form.data.exerciseType == 'American' ? form.data.startDate : undefined,
                'startDateConv': form.data.exerciseType == 'American' ? 'FOLLOWING' : undefined,
                'isIncludeStartDate': form.data.exerciseType == 'American' ? '1' : undefined,
                'frequency': form.data.exerciseType == 'American' ? '1D' : undefined,
                'endDate': form.data.endDate,
                'endDateConv': 'FOLLOWING',
                'isIncludeEndDate': '1',
                'calendar': form.data.calendar
              },
              'observeMode': form.data.exerciseType == 'American' ? 'Discrete' : 'Expire',
              'observeType': 'Close',
              'payStyle': form.data.payStyle,
              'calclationPeriod': {
                'startDate': form.data.effectiveDate,
                'startDateConv': 'FOLLOWING',
                'isIncludeStartDate': '0',
                'endDate': form.data.terminationDate,
                'endDateConv': 'FOLLOWING',
                'calendar': form.data.calendar,
                'isIncludeEndDate': '1'
              },
              'basicYields': {
                'paymentAmount': '',
                'paymentAmountPecentage': form.data.rebateRate / 100,
                'daycounter': form.data.midMoneynessOption == '1' ? form.data.daycounter : '',
                /*xpp 这里 常先号要求写死1*/
                'participationRate': '1'
              }
            },
            'unTrigger': {
              'payDirection': form.data.payDirection,
              'calclationPeriod': {
                'startDate': form.data.effectiveDate,
                'startDateConv': 'FOLLOWING',
                'isIncludeStartDate': '0',
                'endDate': form.data.terminationDate,
                'endDateConv': 'FOLLOWING',
                'calendar': form.data.calendar,
                'isIncludeEndDate': '1'
              },
              'vanillaEuropean': {
                'payDirection': form.data.payDirection,
                'optionType': form.data.optionType,
                'strike': form.data.strike,
                'strikePercentage': form.data.strikePercentage / 100,
                'daycounter': form.data.moneynessOption == '1' ? form.data.daycounter : '',
                'participationRate': Number(form.data.participationRate) / 100,
              },
              'minimumYields': [
                {
                  'paymentAmount': '',
                  'paymentAmountPecentage': form.data.minYieldRate / 100,
                  'daycounter': form.data.lowMoneynessOption == '1' ? form.data.daycounter : '',
                  // 'participationRate': Number(form.data.participationRate) / 100,
                  /*xpp 这里 常先号要求写死1*/
                  'participationRate': '1'
                }
              ]
            },
            // 'strikePercentage': form.data.strikePercentage/100,
            'numberOfOptions': '1',
            'optionEntitlement': form.data.spotPrice == '0' ? form.data.optionEntitlement : form.data.notional / form.data.spotPrice,
            'fixingRounding': '-1',
            'settlementDate': '',
            'settlementDateConv': 'FOLLOWING',
            'settlementDateCalendar': form.data.calendar,
            'settlementDateOffset': form.data.paymentDaysOffset + 'D',
            /*后续可能删除 start*/
            "settlementPrecision": {
              "type": "",
              "OriginReturnPrecision": "",
              "AnnualAdjustIncludedPrecision": "",
              "PartiRateIncludedPrecision": "",
              "AmountPrecision": ""
            },
            /*后续可能删除 end*/
          }
        ],
      },
    },
    calcPricingParam: {
      valueDate: props.valueDate,
      cfgId: props.cfgId,
      calcPPCode: calcPriceParam.calcPPCode,
      underlyingPricingParams: [
        {
          underlyingID: form.data.instrumentId,
          dividend: calcPriceParam.dividend,
          volSurface: calcPriceParam.volSurface,
          funding: calcPriceParam.discount,
          spotPrice: calcPriceParam.spotPrice,
          spotQuoteType: calcPriceParam.spotQuoteType
        }
      ],
      discount: calcPriceParam.discount,
      'customPricingParam': {}
    },
    underlyingMarkets: [
      {
        'underlyingID': form.data.instrumentId,
        'fixingPrices': [],
        'observerPrices': []
      }
    ]
  }

  let calcInstrumentForm = toRaw(form.data)
  let result = props.result
  let json = {
    otcOption: otcOption,
    calcInstrumentForm: calcInstrumentForm,
    calcPricingForm: calcPriceParam,
    calcResultForm: result
  }
  return json;
}

/**
 * 入参
 * */
const getInstrumentJson = async () => {
  return new Promise((resolve) => {
    proxy.$refs['formRef'].validate(valid => {
      if (valid) {
        validateDates(form)
        if (form.data.exerciseType == 'American') {
          if (form.data.minYieldRate > 0) {
            if (Number(form.data.minYieldRate) >= Number(form.data.rebateRate)) {
              proxy.$modal.alertWarning('最低收益不能大于补偿收益,请核对!')
              return
            }
          }
        }
        if (form.data.priceOnWait == '1'){
          if(
              (Number(form.data.triggerRate) ==0 && Number(form.data.strike) ==0 )
              ||
              (Number(form.data.triggerPrice) ==0 && Number(form.data.strikePercentage) ==0 )

          ){
            proxy.$modal.alertWarning('期初价格待定情况下,输入障碍价和行权价时。请仅使用比例或仅使用金额!')
            return
          }
        }
        if (form.data.optionType == 'Call' && Number(form.data.triggerRate) <= Number(form.data.strikePercentage)
            && Number(form.data.triggerPrice) <= Number(form.data.strike)
        ) {
          proxy.$modal.alertWarning('障碍价必须大于行权价,请核对!')
          return
        }
        if (form.data.optionType == 'Put' && Number(form.data.triggerRate) >= Number(form.data.strikePercentage)
            && Number(form.data.triggerPrice) >= Number(form.data.strike)
        ) {
          proxy.$modal.alertWarning('障碍价必须小于行权价,请核对!')
          return
        }
        // //欧式 障碍价比例加保底收益率必须大于行权价比例加敲出补偿比例
        // if (form.data.exerciseType !== 'American' && proxy.lsh.add(Number(form.data.triggerRate), Number(form.data.minYieldRate)) <= proxy.lsh.add(Number(form.data.rebateRate), Number(form.data.strikePercentage))) {
        //   proxy.$modal.alertWarning('障碍价比例+最低收益率必须大于行权价比例+敲出补偿比例,请核对!')
        //   return
        // }
        let json = convertJson();
        resolve(json)
      } else {
        resolve('')
      }
    })
  })
}
/**
 * 保存交易
 * */
const save2Trade = () => {
  getInstrumentJson().then((res) => {
    if (Boolean(res)) {
      props.save2Trade(res, props.index)
    }
  })
}
/**
 * 反算参数 marketNPV
 * */
const marketNPV = () => {
  getInstrumentJson().then((res) => {
    if (Boolean(res)) {
      showVolRatesResult.value = true
      let {otcOption} = res
      proxy.$refs.resultCompRef.getNewNpv()
      res['instrument'] = otcOption.instrument
      res.otcOption.calcPricingParam['marketNPV'] = proxy.$refs.resultCompRef.getNewNpv()
      res.otcOption.calcPricingParam['VolAnnualDays'] = "252"
      res['calcPricingParam'] = res.otcOption.calcPricingParam
      props.marketNPV(res.otcOption, props.index)
    }
  })

}

function assignmentInvertData(f,ratiosTargets,result,fData) {
  let amounts = result.amounts.double;
  let ratios = result.ratios.double;
  ratiosTargets = f(ratiosTargets,ratios)
  let amountsTargets = [];
  let {typeStr, labelAmountStr, labelPercentageStr} = fData
  amountsTargets = ratiosTargets.map(item => amounts[ratios.indexOf(item)])
  calcInvertVisible.value = true
  Dialog.type = typeStr

  Dialog.data = []
  for (let i = 0; i < ratiosTargets.length; i++) {
    let item = {}
    item.valueAmount = amountsTargets[i];
    item.valuePercentage = ratiosTargets[i] * 100;
    item.labelAmount = labelAmountStr
    item.labelPercentage = labelPercentageStr
    Dialog.data.push(item)
  }
  proxy.$modal.msgSuccess("计算成功！");
}

//反算逻辑
const calcInvert = () => {
  let json = convertJson("invert");
  let {newNpv, yearnpvPercentage, npvPercentage, showSwitch} = proxy.$refs.resultCompRef.getData();
  if (showSwitch) {
    if (isVoid(yearnpvPercentage)) {
      proxy.$modal.msgWarning("请填入npv%");
      return;
    }
  } else {
    if (isVoid(npvPercentage)) {
      proxy.$modal.msgWarning("请填入npv%");
      return;
    }
  }
  json.otcOption.calcPricingParam["marketNPV"] = form.data.notional * npvPercentage / 100;
  let eleArr = [form.data.strikePercentage, form.data.rebateRate, form.data.minYieldRate, form.data.triggerRate];
  let zeroItems = eleArr.filter(item => item != '0.00').length
  /*不能全是0.0，也不能超过1个0*/
  switch (zeroItems) {
    case 4: {
      proxy.$modal.msgWarning("请空出反算要素");
      return;
    }
      ;
      break
    case 2:
    case 1: {
      proxy.$modal.msgWarning("请填入适当反算要素");
      return;
    }
      ;
      break
  }
  //行权价/比例
  if (form.data.strikePercentage == '0.00') {
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.STRIKE,
          "index": 0
        }
      ]
    }
   /* // 看涨：[0.01*期初价格，障碍价格）
    if (form.data.optionType == 'Call') {
      json.otcOption["sectionSolvers"] =
          {"cap":form.data.triggerPrice,"floor":0.01*form.data.spotPrice,"step":2}
    }
    // 看跌：（障碍价格，2*期初价格]
    if (form.data.optionType == 'Put') {
      json.otcOption["sectionSolvers"] =
          {"cap": 2 * form.data.spotPrice,"floor":form.data.triggerPrice,"step":2}
    }*/
    calcContractParamProxy(json.otcOption).then((result) => {

      let ratiosTargets = [];
      //todo 多个返回值时舍去值的逻辑
      //对看涨单鲨  行权价<敲出障碍价否则为无效取值

      let  fData = {
        "labelAmountStr" :"行权价",
        "labelPercentageStr" :"行权价比例",
        "typeStr" : "strikePercentage"
      }

      function f(ratiosTargets,ratios) {
        if (form.data.optionType == 'Call') {
          ratiosTargets = ratios.filter(item => item * 100 < form.data.triggerRate)
        }
        //对看跌单鲨 行权价>敲出障碍价否则为无效取值
        if (form.data.optionType == 'Put') {
          ratiosTargets = ratios.filter(item => item * 100 > form.data.triggerRate)
        }
        form.data.strikePercentage = ratiosTargets[0] * 100
        linkPercentage(form,form.data.strikePercentage,form.data.spotPrice,'data.strike')
        return ratiosTargets
      }
      Dialog.showMoneynessOption = false


      assignmentInvertData(f, ratiosTargets, result, fData);
      proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''

    })

  }
  //反算敲出收益
  if (form.data.rebateRate == '0.00') {
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.KNOCK_OUT_PAYOFF,
          "index": 0
        }
      ]
    }
    calcContractParamProxy(json.otcOption).then((result) => {
      let ratiosTargets = [];
      Dialog.moneynessOption = form.data.midMoneynessOption
      let  fData = {
        "labelAmountStr" :"敲出补偿",
        "labelPercentageStr" : "敲出收益率",
        "typeStr" : "rebateRate"
      }

      function f(ratiosTargets,ratios) {
        form.data.rebateRate = ratios[0]*100;
        onRebateRateChange()
        return ratios
      }


      assignmentInvertData(f, ratiosTargets, result, fData);
    })
  }
  //最低收益
  if (form.data.minYieldRate == '0.00') {

    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.UNTRIGGER_MINIMUM_PAYOFF,
          "index": 0
        }
      ]
    }
    calcContractParamProxy(json.otcOption).then((result) => {

      Dialog.showMoneynessOption = true;
      Dialog.moneynessOption = form.data.lowMoneynessOption

      let ratiosTargets = [];

      let  fData = {
        "labelAmountStr" :"最低收益",
        "labelPercentageStr" : "最低收益率",
        "typeStr" : "minYieldRate"
      }

      function f(ratiosTargets,ratios) {
        form.data.minYieldRate = ratios[0]*100;
        onMinYieldRateChange()
        return ratios
      }
      assignmentInvertData(f, ratiosTargets, result, fData);
    })
  }
  // 敲出障碍价
  if (form.data.triggerRate == '0.00') {

    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.TRIGGER_LEVEL,
          "index": 0
        }
      ]
    }
   /* // 看涨：（行权价格, 2*期初价格]
    if (form.data.optionType == 'Call') {

      json.otcOption["sectionSolvers"] =
          {"cap":2*form.data.spotPrice,"floor":form.data.strike,"step":2}
    }
    // 看跌：[0.01*期初价格，行权价格)
    if (form.data.optionType == 'Put') {

      json.otcOption["sectionSolvers"] =
          {"cap":form.data.strike,"floor":0.01*form.data.spotPrice,"step":2}
    }*/

    calcContractParamProxy(json.otcOption).then((result) => {

      Dialog.showMoneynessOption = false;
      let ratiosTargets = [];
      let  fData = {
        "labelAmountStr" :"敲出障碍价",
        "labelPercentageStr" : "敲出障碍价比例",
        "typeStr" : "triggerRate"
      }
      function f(ratiosTargets,ratios) {
          //对看涨单鲨  行权价<敲出障碍价否则为无效取值
          if (form.data.optionType == 'Call') {
            ratiosTargets = ratios.filter(item => item * 100 > form.data.strikePercentage)
          }
          //对看跌单鲨 行权价>敲出障碍价否则为无效取值
          if (form.data.optionType == 'Put') {
            ratiosTargets = ratios.filter(item => item * 100 < form.data.strikePercentage)
          }
        form.data.triggerRate = ratiosTargets[0]*100;
        linkPercentage(form,form.data.triggerRate,form.data.spotPrice,'data.triggerPrice')
        return ratiosTargets
      }
      assignmentInvertData(f, ratiosTargets, result, fData);
    })

  }

}

const dbClickForInvert = (row) => {
  let {labelAmount,valueAmount, valuePercentage} = row;
  switch (labelAmount){
    case "行权价":{
      form.data.strikePercentage = valuePercentage;
      linkPercentage(form,form.data.strikePercentage,form.data.spotPrice,'data.strike')
      calc()
    };break;
    case "敲出补偿":{
      form.data.rebateRate = valuePercentage;onRebateRateChange();
      calc()
    };break;
    case "敲出障碍价":{
      form.data.triggerRate = valuePercentage;linkPercentage(form,form.data.triggerRate,form.data.spotPrice,'data.triggerPrice')
      calc()
    };break;
    case "最低收益":{
      form.data.minYieldRate = valuePercentage;onMinYieldRateChange();
      calc()
    };break;
  }
}
/**
 * 保存草稿
 * */
const save2CalcLog = () => {
  getInstrumentJson().then((res) => {
    if (Boolean(res)) props.save2CalcLog(res, props.index)
  })
}
/**
 * 获取定价参数
 * */
const getCalcPriceParam = (calcType) => {
  let calcPriceParam = proxy.$refs.PricingParamRef.getCalcPricingParam(calcType)
  return calcPriceParam
}
/**
 * 获取 form
 * */
const getFormData = () => {
  return form
}

defineExpose({
  calc, getPricingCfg, getCalcPriceParam, getFormData, getInstrumentJson,proxy
})

onMounted(() => {
  form.initFlag = props.isReCalc
  if (props.formData != null) {
    form.initFlag = isNotVoid(props.calcPricingParam)
    let data = props.formData.data || props.formData
    form.data = Object.assign(form.data, data)
  }
  // 这里获取DOM的value是旧值
  nextTick(()=>{
    form.initFlag = false
  })

})
watch(() => proxy.$attrs.disabled, (nv) => {
  form.data.readOnly = nv
}, {
  immediate: true
})
/**
 * 获取标的价格
 * */
const setSpotPrice = () => {
  setCommonSpotPrice(proxy, form, props)
}
/*观察结束日变化时，更新曲面插值*/
const endDateChange = ()=>{
  if ("American" == form.data.exerciseType) {
    proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }
}
watch(()=>form,()=>{

  proxy.$attrs.cacheFormData()
},{deep:true})
</script>

<style>

</style>

